import { load } from 'cheerio'
import { trim, startsWith } from 'lodash'
import { parseRule } from './parser'
import { parse } from 'querystring'

function parseList (doc: string, listRule: string, itemRules: Record<string, string>) {
  let $: cheerio.Root
  if (typeof doc === 'string') {
    $ = load(doc)
  } else {
    $ = doc
  }

  const list = parseRule(listRule, $) as  cheerio.Cheerio | null
  console.log('parse list', listRule, list?.length)

  if(!list || list.length === 0) {
    return null
  }

  const items: Record<string, string>[]  = []

  list.each(function () {
    const item: Record<string, string> = {}
    Object.keys(itemRules).forEach((prop) => {
      // @ts-ignore
      const value = trim(parseRule(itemRules[prop], $(this)) as string)
      if(value) {
        item[prop] = value
      }
      console.log('parse item', item[prop])
    })
    if(Object.keys(item).length > 0) {
      items.push(item)
    }
  })

  return items
}

function parseSearchUrl (source: any) {
  const offset = source.searchUrl.indexOf(',')
  let options: any = {
    method: 'GET'
  }
  let url
  if (offset === -1) {
    url = source.searchUrl
  } else {
    url = source.searchUrl.slice(0, offset)
    const op = JSON.parse(source.searchUrl.slice(offset + 1))
    options = { ...options, ...op }
  }
  if (source.header) {
    options.headers = JSON.parse(source.header)
  }
  if (!startsWith(url, 'http')) {
    url = source.bookSourceUrl + url
  }

  return { url, options }
}

function formatUnicorn (str: string, args: Record<string, string | number>) {
  for (const key in args) {
    str = str.replace(new RegExp(`\\{{${key}\\}}`, 'gi'), args[key] + '')
  }

  return str
}

const v2 = {
  formatUrl (url: string) {
    let newUrl = url
    const keys: Record<string, string> = { searchPage: 'page', searchKey: 'key' }
    Object.keys(keys).forEach(key => {
      newUrl = newUrl.replace('=' + key, `={{${keys[key]}}}`)
    })
    return newUrl
  },
  parseSearchUrl (source: any) {
    const [searchUrl, optionsUrl] = source.ruleSearchUrl.split('|')
    const options: any = {
      method: 'GET'
    }
    if (optionsUrl) {
      const op = parse(optionsUrl)
      if (op.char) {
        options.charset = op.char
      }
    }
    if (source.httpUserAgent) {
      options.headers = {
        'User-Agent': source.httpUserAgent
      }
    }
    let url = ''
    if (searchUrl.indexOf('@') !== -1) {
      options.method = 'POST'
      const parseUrlObj = searchUrl.split('@')
      url = parseUrlObj[0]
      options.body = v2.formatUrl(parseUrlObj[1])
    } else {
      url = v2.formatUrl(searchUrl)
    }

    return { url, options }
  }
}

export {
  parseList,
  parseSearchUrl,
  formatUnicorn,
  v2
}
